大家好,今天來介紹泛型Generics。
當我們希望函式、介面或類別能夠適用於不同型別,同時又希望保留型別資訊與型別檢查時,就可以使用泛型。泛型可以讓我們先使用一個型別參數代表某種型別,再於實際使用時決定它所代表的型別。
假設我們要回傳三個基本型別(string、boolean、number),不可能寫三個重複的函式,這時能夠使用泛型<T>:
//不使用泛型的場合:
function returnString(value: string): string {
return value;
}
function returnBoolean(value: boolean): boolean {
return value;
}
function returnNumber(value: number): number {
return value;
}
//光是回傳三個型別就要寫三個近乎一模一樣的函式
//使用泛型的場合:
function returnValue<T>(value: T): T {
return value;
} //函式中的T是Type的意思,是泛型常見的型別名稱
//寫上要回傳的型別:
const stringValue = returnValue<string>("Hello"); //合法
const booleanValue = returnValue<boolean>(true); //合法
const numberValue = returnValue<number>(100); //合法
//由此可知,使用泛型可以減少重複撰寫相似函式的情況,同時保留型別資訊與型別檢查
//讓同一個函式能夠處理不同型別的資料。
需要注意的是,可能有人覺得同樣的情況下,直接將
value設成any也是可行的,但any在之前的文章提過,使用any會失去型別檢查的功能,因此,在保留型別檢查的情況下,泛型通常比any更適合。
在沒有寫出型別的情況下,TypeScript(TS)也能對泛型做出型別推論,拿上方程式碼來舉例:
function returnValue<T>(value: T): T {
return value;
}
const value_1 = returnValue("Hello"); //TS會推論出string
const value_2 = returnValue(false); //boolean
const value_3 = returnValue(54); //number
除了運用在函式外,泛型也能用在陣列及介面中:
//陣列:
const food_1: string[] = ["apple", "steak", "tuna"];
const food_2: Array<string> = ["apple", "steak", "tuna"]; //泛型用法
//介面:
interface Box<T> { //能夠訂定介面的型別
name: T; //也能在屬性上使用泛型型別
value: number;
}
interface Box<T> {
name: T;
value: number;
}
const box1: Box<string> = {
name: "apple",
value: 100
};
const box2: Box<number> = {
name: 123,
value: 100
};
當我們想在函式或介面、類別接收一個以上的型別資料,泛型也能做到多個型別名稱設定:
function student<T,U>(name:T, age:U) { //T跟U都是型別參數
return [name, age];
}
let student1 = student("Owen", 19); //T = string,U = number
let student2 = student<string, number> ("Judy", 20);
今天簡單介紹了泛型的應用,明天會接著泛型的內容介紹泛型約束,那麼,大家明天見啦!